package cn.biplam.back.bean.sqlengine.datatype;

import java.math.BigDecimal;

import cn.biplam.common.paramters.Field_Data_Type;
import cn.biplam.common.paramters.DatabaseType.DataBase_Type;
import cn.biplam.common.tools.TOOLS;
import cn.biplam.common.wrapper.ErrorMessage;

public class DataTypeUtil {


	/**
	 * 根据数据库类型和数据类型，取条件字符串
	 * @param dataBaseType 数据库类型
	 * @param dataType     数据类型
	 * @param value        数据字符串
	 * @return
	 * @throws ErrorMessage 
	 */
	public static String getValueByDataType(String dataBaseType,String dataType,String value) throws ErrorMessage{
		if("1".equals(dataBaseType)){
			/**oracle*/
			value = getValueOracle(dataType, value);
		}
		return value;
	}

	/**
	 * 根据数据类型，取条件字符串(oracle)
	 * @param dataType     数据类型
	 * @param value        数据字符串
	 * @return
	 * @throws ErrorMessage 
	 */
	private static String getValueOracle(String dataType,String value) throws ErrorMessage{
		if(dataType!=null){
			if(Field_Data_Type.CHAR.toString().equals(dataType)){
				value = "'"+value+"'";
			}else if(Field_Data_Type.DATE.toString().equals(dataType)){
				value = "to_date('"+value+"','yyyy-mm-dd hh24:mi:ss')";
			}else if(Field_Data_Type.BLOB.toString().equals(dataType)){
				throw new ErrorMessage("DataType is BLOB ,can not compare");
			}
		}

		return value;
	}

	/**
	 * 根据数据库类型和数据类型，取条件字符串
	 * @param dataBaseType  数据库类型
	 * @param dataType      数据类型
	 * @param value         字段
	 * @return
	 * @throws ErrorMessage 
	 */
	public static String getEmptyByDataType(String dataBaseType,String dataType,String value) throws ErrorMessage{
		if("1".equals(dataBaseType)){
			/**oracle*/
			value = getEmptyOracle(dataType, value);
		}
		return value;
	}

	/**
	 * 根据数据类型，取条件字符串(oracle)
	 * @param dataType     数据类型
	 * @param value        字段
	 * @return	String
	 * @throws ErrorMessage 
	 */
	private static String getEmptyOracle(String dataType,String value) throws ErrorMessage{

		if(dataType!=null){
			if(Field_Data_Type.CHAR.toString().equals(dataType)){
				value = "trim("+value+")='' ";
			}else if(Field_Data_Type.INT.toString().equals(dataType) ||
					Field_Data_Type.NUMBER.toString().equals(dataType) ||
					Field_Data_Type.DECIMAL.toString().equals(dataType)){
				value = value + "=0 ";
			}else if(Field_Data_Type.VARCHAR.toString().equals(dataType)){
				value = value + "='' ";
			}else if(Field_Data_Type.BLOB.toString().equals(dataType)){
				throw new ErrorMessage("DataType is BLOB ,can not compare");
			}else{
				value = value + "='' ";
			}
		}

		return value;
	}

	/**
	 * 获取Float数据类型的长度(目前只对Oracle数据库字典的Float处理，其他数据库不特殊处理)
	 * Oracle数据库中存储的中float的数据长度为binary precision，而不是我们常用的decimal precision。他们之间的换算关系是：
	 * binary precision＝int(b*0.30103)，在从数据库中扫描表结构时读出的float数据类型的长度为126，精度为-1
	 * 在将float转换成Decimal类型时需要将数据精度转换成decimal precision
	 * @param iPrecision
	 * @return
	 */
	public static int getFloatPrecision(String dbType,int iPercision){
		String percision = null;
		if(DataBase_Type.Oracle.toString().equals(dbType)){
			percision = String.valueOf(iPercision*0.30103);
			percision = new BigDecimal(percision).setScale(0, BigDecimal.ROUND_HALF_UP).toString();
			return TOOLS.stringToInt(percision);
		}else{
			return iPercision;
		}
	}

	/**
	 * 处理Float类型的小数点后有效位数（目前只对Oracle进行特殊处理，其他数据库返回传入值）
	 * @param dbType     数据库类型
	 * @param iPercision 有效位数
	 * @return 如果设置了小数点后有效位数直接返回，否则返回16
	 */
	public static int getFloatScale(String dbType,int iScale){
		if(DataBase_Type.Oracle.toString().equals(dbType)){
			if(iScale<-84){
				iScale = 15;
			}
		}
		return iScale;
	}


	/**
	 * 获取数据类型文本描述    
	 * @param dataType     数据类型名
	 * @param sPrecision   数据长度
	 * @param sScale       数据精度
	 * @return 数据类型名(数据长度,数据精度)
	 * @throws ErrorMessage 
	 */
	public static String getDataTypeDesc(String dataType,String dataPrecision,String dataScale) throws ErrorMessage{
		if(TOOLS.StringIsEmpty(dataType)){
			return "";
		}
		StringBuilder dataTypeDesc = new StringBuilder();
		String dataTypeName = getDataTypeDescByCode(dataType);
		dataTypeDesc.append(dataTypeName);
		if(Field_Data_Type.INT.toString().equals(dataType) ||
				Field_Data_Type.DATE.toString().equals(dataType)||
				Field_Data_Type.BLOB.toString().equals(dataType)){
			return dataTypeDesc.toString();
		}
		if (dataPrecision != null && !"".equals(dataPrecision)) {
			dataTypeDesc.append("(");
			dataTypeDesc.append(dataPrecision);
			if (dataScale != null && !"".equals(dataScale)) {
				dataTypeDesc.append(",");
				dataTypeDesc.append(dataScale);
			}
			dataTypeDesc.append(")");
		}
		return dataTypeDesc.toString();
	}

	/**
	 * 根据数据类型代码获取数据类型名称
	 * @param typeCode 数据类型代码
	 * @return 数据类型名称
	 * @throws ErrorMessage
	 */
	public static String getDataTypeDescByCode(String typeCode) throws ErrorMessage{
		switch(TOOLS.stringToInt(typeCode)){
		case 1:
			return "CHAR";
		case 2:
			return "INT";
		case 3:
			return "VARCHAR";
		case 4:
			return "NUMBER";
		case 5:
			return "DATE";
		case 6:
			return "DECIMAL";
		case 7:
			return "BLOB";
		default:
			throw new ErrorMessage("Data type "+typeCode+"is unknown!");
		}
	}
}

